﻿Imports System.Runtime.CompilerServices
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Text.RegularExpressions
Imports System.Xml
Imports System.Xml.Linq

<Extension()> _
Module ExtensionMethods

    <Extension()> _
    Public Function SoapExceptionDetail(ByVal exception As FaultException) As String
        Dim messageFault As MessageFault = exception.CreateMessageFault()
        If messageFault.HasDetail Then
            Dim detail As XmlElement = messageFault.GetDetail(Of XmlElement)()
            Return detail.InnerText
        Else
            Return String.Empty
        End If
    End Function

    <Extension()> _
    Public Function ToXmlElement(ByVal element As XElement) As XmlElement
        Return CType((New XmlDocument).ReadNode(element.CreateReader()), XmlElement)
    End Function

    <Extension()> _
    Public Function ToFieldType(ByVal typeEnum As SharePointField.TypeEnum) As SP.Copy.FieldType
        Select Case typeEnum
            Case SharePointField.TypeEnum.Bool
                Return SP.Copy.FieldType.Boolean
            Case SharePointField.TypeEnum.SingleChoice, SharePointField.TypeEnum.ObsoleteChoice
                Return SP.Copy.FieldType.Choice
            Case SharePointField.TypeEnum.MultiChoice
                Return SP.Copy.FieldType.MultiChoice
            Case SharePointField.TypeEnum.Currency
                Return SP.Copy.FieldType.Currency
            Case SharePointField.TypeEnum.DateTime
                Return SP.Copy.FieldType.DateTime
            Case SharePointField.TypeEnum.Note
                Return SP.Copy.FieldType.Note
            Case SharePointField.TypeEnum.Number
                Return SP.Copy.FieldType.Number
            Case SharePointField.TypeEnum.Text
                Return SP.Copy.FieldType.Text
            Case SharePointField.TypeEnum.Url
                Return SP.Copy.FieldType.URL
            Case Else
                Return SP.Copy.FieldType.Text
        End Select
    End Function

    <Extension()> _
    Public Function AttributeOrDefault(ByVal element As XElement, ByVal name As XName, ByVal defaultValue As String) As String
        Dim attribute = element.Attribute(name)
        If attribute Is Nothing Then
            Return defaultValue
        Else
            Return attribute.Value
        End If
    End Function

    <Extension()> _
    Public Function Append(ByVal url As Uri, ByVal value As String) As Uri
        If String.IsNullOrEmpty(value) Then
            Return url
        End If

        Return New Uri(String.Format("{0}/{1}", Regex.Replace(url.ToString(), "[ /]+$", String.Empty), value))
    End Function

    <Extension()> _
    Public Function AppendFolder(ByVal url As Uri, ByVal value As String) As Uri
        If String.IsNullOrEmpty(value) Then
            Return url
        End If

        Return New Uri(String.Format("{0}/{1}/", url.ToString().TrimEnd(" /".ToCharArray()), value.TrimEnd(" /".ToCharArray())))
    End Function

    <Extension()> _
    Public Function Parent(ByVal url As Uri) As Uri
        Return New Uri(Regex.Replace(url.ToString(), "/[^/]+/$|/[^/]+$", String.Empty))
    End Function

    <Extension()> _
    Public Function LastSegment(ByVal url As Uri) As String
        Return Uri.UnescapeDataString(Regex.Replace(url.Segments.Last(), "^[ /]|[ /]$", String.Empty))
    End Function

    <Extension()> _
    Public Function ToSharePointString(ByVal uploadField As String, ByVal type As SharePointField.TypeEnum, ByVal dateInUtc As Boolean) As String
        Dim strValue = uploadField.Trim()
        If Not uploadField = "" Then
            Select Case type
                Case SharePointField.TypeEnum.DateTime
                    If dateInUtc Then
                        Return ToUtcSupportHistory(DateTime.Parse(strValue)).ToString("yyyy-MM-ddTHH:mm:ssZ")
                    Else
                        Return DateTime.Parse(strValue).ToUniversalTime().ToString("u")
                    End If

                Case SharePointField.TypeEnum.Bool
                    Dim bValue As Boolean = False
                    If (strValue = "1") Or (LCase(strValue) = "yes") Or (LCase(strValue) = "true") Then
                        Return "True"
                    Else
                        If (strValue = "0") Or (LCase(strValue) = "no") Or (LCase(strValue) = "false") Then
                            Return "False"
                        Else
                            Return "False"
                        End If
                    End If
                Case SharePointField.TypeEnum.Number
                    If strValue = "" Then
                        Return "0"
                    ElseIf strValue.EndsWith("e") Or strValue.EndsWith("E") Then
                        Return strValue & "0"
                    End If
                    Dim dValue As Double
                    dValue = CDbl(strValue)
                    Return dValue.ToString()
                Case SharePointField.TypeEnum.Currency
                    If (strValue = "") Then
                        Return "0"
                    ElseIf strValue.EndsWith("e") Or strValue.EndsWith("E") Then
                        Return strValue & "0"
                    End If
                    Dim dValue As Double
                    dValue = CDbl(strValue)
                    Return dValue.ToString()
            End Select
        End If

        Return strValue
    End Function

    Private Function ToUtcSupportHistory(ByVal dateTimeValue As Date) As Date
        Dim currentTZ = TimeZone.CurrentTimeZone
        Dim tzi As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(currentTZ.StandardName)
        Dim utcOffset = tzi.GetUtcOffset(dateTimeValue)
        Return dateTimeValue.Add(-utcOffset)
    End Function

    <Extension()> _
    Public Function WcfSecurityMode(ByVal url As Uri) As BasicHttpSecurityMode
        If url.Scheme = "https" Then
            Return BasicHttpSecurityMode.Transport
        Else
            Return BasicHttpSecurityMode.TransportCredentialOnly
        End If
    End Function

End Module
